mod lexer;
mod token;

mod parser {
   // parser 运行结果不对
   use crate::lexer::Lexer;
   use crate::token::{Token, TokenKind};

   #[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
   enum PrecedenceLevel {
      Lowest = 0,
      Sum = 1,     // + -
      Product = 2, // * / %
      Power = 3,   // ^
      Prefix = 4,  // 前缀运算符（如负号-, 非运算符!）
   }

   // 运算符优先级映射
   fn precedence_map(kind: &TokenKind) -> PrecedenceLevel {
      match kind {
         TokenKind::Plus | TokenKind::Minus => PrecedenceLevel::Sum,
         TokenKind::Asterisk | TokenKind::Slash => PrecedenceLevel::Product,
         TokenKind::Caret => PrecedenceLevel::Power,
         _ => PrecedenceLevel::Lowest,
      }
   }

   #[derive(Debug, PartialEq)]
   pub enum Expr {
      NumberInt(i64),
      NumberFloat(f64),
      Prefix(TokenKind, Box<Expr>),
      Infix(TokenKind, Box<Expr>, Box<Expr>),
      Grouped(Box<Expr>),
   }

   pub struct Parser {
      lexer: Lexer,
      current_token: Token,
   }

   impl Parser {
      pub fn new(mut lexer: Lexer) -> Self {
         Self {
            lexer: lexer.clone(),
            current_token: lexer.next_token().unwrap_or(Token::eof()),
         }
      }

      pub fn parse(&mut self) -> Expr {
         self.parse_expression(PrecedenceLevel::Lowest)
      }

      fn parse_expression(&mut self, precedence: PrecedenceLevel) -> Expr {
         let mut left = self.parse_prefix();

         println!(">>>>>>>>> {:?}", precedence);

         while precedence <= self.current_precedence() {
            println!("XXXXXXXXXX");
            if let Some(infix_kind) = self.parse_infix() {
               self.advance();
               let right =
                  self.parse_expression(self.token_precedence(&infix_kind));
               left = Expr::Infix(infix_kind, Box::new(left), Box::new(right));
            } else {
               break;
            }
         }

         left
      }

      // 解析前缀表达式（数字、括号、负号）
      fn parse_prefix(&mut self) -> Expr {
         println!("parse_prefix............ {:?}", self.current_token.kind);
         match self.current_token.kind {
            TokenKind::NumberInt(int_number) => {
               let expr = Expr::NumberInt(int_number);
               self.advance();
               expr
            }
            TokenKind::NumberFloat(float_number) => {
               let expr = Expr::NumberFloat(float_number);
               self.advance();
               expr
            }
            TokenKind::Minus => {
               self.advance();
               let expr = self.parse_expression(PrecedenceLevel::Prefix);
               Expr::Prefix(TokenKind::Minus, Box::new(expr))
            }
            TokenKind::LParen => {
               self.advance();
               let expr = self.parse_expression(PrecedenceLevel::Lowest);
               self.expect(TokenKind::RParen);
               Expr::Grouped(Box::new(expr))
            }
            _ => panic!("Unexpected token: {:?}", self.current_token),
         }
      }

      // 解析中缀运算符
      fn parse_infix(&mut self) -> Option<TokenKind> {
         match self.current_token.kind {
            TokenKind::Plus
            | TokenKind::Minus
            | TokenKind::Asterisk
            | TokenKind::Slash
            | TokenKind::Caret => Some(self.current_token.kind.clone()),
            _ => None,
         }
      }

      // 获取当前 token 优先级
      fn current_precedence(&self) -> PrecedenceLevel {
         self.token_precedence(&self.current_token.kind)
      }

      // 运算符优先级映射
      fn token_precedence(&self, kind: &TokenKind) -> PrecedenceLevel {
         precedence_map(kind)
      }

      // 移动到下一个 token
      fn advance(&mut self) {
         self.current_token = self.lexer.next_token().unwrap_or(Token::eof());
      }

      // 校验当前 token
      fn expect(&mut self, kind: TokenKind) {
         if self.current_token.kind == kind {
            self.advance();
         } else {
            panic!("Expected {:?}, found {:?}", kind, self.current_token.kind);
         }
      }
   }
}

fn main() {
   // let input =
   // "if, else, true, false, age, name, a_name, 3.2 + 5 * (10 - 4) / 24e-1 ";
   let input = "3 + 4 * 2 / (1 - 5) ^ 2";
   println!("Code: {input}");

   let mut lexer = lexer::Lexer::new(input);
   while let Some(token) = lexer.next_token() {
      println!("{token:?}");
   }

   // 为每个运算符分配优先级数值和结合性规则：
   // 运算符	优先级	结合性
   // ^	       4	    右结合
   // * /	     3	    左结合
   // + -	     2	    左结合
   // ( )	     0	   特殊处理
   let lexer = lexer::Lexer::new(input);
   let mut parser = parser::Parser::new(lexer);
   let ast = parser.parse();
   println!("Ast: {:?}", ast);
   /*
   Infix(
       Plus,
       Number(3.0),
       Infix(
           Slash,
           Infix(
               Asterisk,
               Number(4.0),
               Number(2.0),
           ),
           Grouped(
               Infix(
                   Caret,
                   Infix(
                       Minus,
                       Number(1.0),
                       Number(5.0),
                   ),
                   Number(2.0),
               )
           )
       )
   )
       */
}
